package com.unknown.chainevent.biz.event;

import com.unknown.chainevent.biz.service.ChainConfigService;
import com.unknown.chainevent.biz.service.ContractConfigService;
import com.unknown.chainevent.biz.service.ContractLogsService;
import com.unknown.chainevent.common.constants.ChainEventConstants.ChainStatusConstants;
import com.unknown.chainevent.common.entity.ChainConfig;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.cloud.utils.CollectionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 初始化链订阅
 */
@Slf4j
@Component
public class InitLogFilter {

    @Autowired
    private ChainConfigService chainConfigService;
    @Autowired
    private ContractConfigService contractConfigService;
    @Autowired
    private ContractLogsService contractLogsService;
    private final Map<Long, BaseLogFilter> chainLogFilters = new HashMap<>();

    public void initSubscribe() throws IOException {
        List<ChainConfig> chainList = chainConfigService.getChainList(false);
        if (CollectionUtil.single().isEmpty(chainList)) {
            return;
        }
        for (var chainConfig : chainList) {
            createLogFilter(chainConfig);
        }
    }

    public void clearLogFilter(Long chainConfigId) {
        BaseLogFilter baseLogFilter = chainLogFilters.get(chainConfigId);
        if (baseLogFilter != null) {
            baseLogFilter.stop();
            baseLogFilter.RE_INIT.compareAndSet(false, true);
        }
    }

    private void createLogFilter(ChainConfig chainConfig) throws IOException {
        BaseLogFilter baseLogFilter = chainLogFilters.get(chainConfig.getChainConfigId());
        if (baseLogFilter == null) {
            baseLogFilter = getLogFilter(chainConfig);
            chainLogFilters.put(chainConfig.getChainConfigId(), baseLogFilter);
            baseLogFilter.startTask();
        } else if (baseLogFilter.RE_INIT.get()) {
            log.info("chainId:{},symbol:{}, chainLogFilter is reInit", chainConfig.getChainConfigId(), chainConfig.getChainSymbol());
            baseLogFilter.stop();
            baseLogFilter.setChainConfig(chainConfig);
            baseLogFilter.initWeb3();
            baseLogFilter.initContract();
            baseLogFilter.setLastBlock(chainConfig.getBlockNumber());
            baseLogFilter.RE_INIT.compareAndSet(true, false);
        }
        if (chainConfig.getChainStatus().equals(ChainStatusConstants.FORBIDDEN.getStatus())) {
            baseLogFilter.stop();
        } else {
            baseLogFilter.start();
        }
    }

    private BaseLogFilter getLogFilter(ChainConfig chainConfig) throws IOException {
        return new EVMCommonLogFilter(chainConfigService, contractConfigService, contractLogsService, chainConfig);
    }
}
